import message,base
import clientQ,clientso
import time
import threading

class clientdo(message.Ft_message):
    def __init__(self,ser_address):
        super(clientdo,self).__init__()
        self.__ikey = 0
        self.__uplist = []
        self.__qlogin = clientQ.Qlogin(self.do_Qloginok)
        self.__qlogin.show()
        self.__qonline = clientQ.Qonline()
        self.__qonline.setSaysf(self.do_Qdata)
        self.__thr_event = threading.Event()# 由于pyqt show不能在非ui线程中执行，所以这里引入线程事件，在用户登录中使用
        self.__clientso = clientso.clientso(self.do_serverdata,self.do_socon,ser_address,self.__thr_event)
        self.__clientso.start()#底层先连，它对用户看不见
        #self.__qonline.show()
        #self.__isonline = False#登录标记，如果登录则True
        self.__name = None
        self.__rejreason = None
        self._setlogName('ClientDo')
        self._log('clientdo init over.')
        pass

    #处理login ok
    def do_Qloginok(self,id,password):
        if id =='' or password =='':
            return -99
        id = int(id)
        password = str(password)
        self.__ikey = id
        #发起验证
        send_bytes = self.pack_auth_req(id, password)
        ret = self.__clientso.sendtoserver(send_bytes)
        if ret == -1:
            self._log('数据发送失败,可能底层连接未完成',self.LOG_DEBUG)
            return -1
        else: #此条件待优化，目前为wait，如果发送了请求，服务器异常，则此处会一直收不到恢复事件
            self.__thr_event.wait(5)

            if self.__name is not None:
                self.__qlogin.close()
                self.__qonline.show()
            else:
                if self.__rejreason is None:
                    self._log('未能登录，可能服务器异常',self.LOG_DEBUG)
                    return -4
                elif self.__rejreason == 3:
                    self._log('不能重复登录',self.LOG_DEBUG)
                    return -3
                else:
                    self._log('登录认证失败，用户名和密码错误或未注册',self.LOG_DEBUG)
                    return -2
                pass

    def do_Qdata(self,isfamily,says,saysto = 0):#saysto is saysto id or saysto groupid
        saysto = int(saysto)

        if isfamily:
            send_bytes = self.pack_dialog(self.__ikey, saysto, True, 1, 0, says)
            self._log("send dialog in family:%s" % send_bytes, self.LOG_DEBUG)
            self.__clientso.sendtoserver(send_bytes)
        else:
            send_bytes = self.pack_dialog(self.__ikey, saysto, False, 1, 0, says)
            self._log("send dialog:%s" % send_bytes, self.LOG_DEBUG)
            self.__clientso.sendtoserver(send_bytes)

    #以下内部方法提供给do_serverdata使用
    def __do_auth_ack(self, name, thr_event):
        self.__name = name
        thr_event.set()#通知ui线程继续
        self.__qonline.setsaysme(self.__ikey,name)

    def __do_auth_rej(self, reason, thr_event):
        self.__name = None
        self.__rejreason = reason
        thr_event.set()
        self._log('auth reject,reason is %d' % reason)

    def do_serverdata(self,ftmsg_bytes,thr_event):
        t,v_bytes = self.unpack(ftmsg_bytes)

        if t == self.MSGC_SC_AUTH_ACK:
            self._log('recv auth ack.')
            self.__name = self.unpack_auth_ack(v_bytes)
            self.__do_auth_ack(self.__name,thr_event)
        elif t == self.MSGC_SC_AUTH_REJ:
            self._log('recv auth rej')
            reason = self.unpack_auth_rej(v_bytes)
            self.__do_auth_rej(reason,thr_event)
        elif t == self.MSGC_SC_RF_UPDATE:
            self.__rfdict = self.unpack_rf_update(v_bytes)
            self._log("recv rf update:%s" % str(self.__rfdict), self.LOG_INFO)
            self.__qonline.setrf(self.__rfdict)
        elif t == self.MSGD_DIALOG:
            sayswho, saysto, issaysinfamily, familyid, saystime, says = self.unpack_dialog(v_bytes)
            self.__qonline.recvsays(sayswho, saysto, issaysinfamily, familyid, saystime, says )
        elif t == self.MSGD_SC_LEAVESAYS:
            leavesayslist = self.unpack_leavesays(v_bytes)
            self._log("recv leavesays:", self.LOG_DEBUG)
            print(leavesayslist)
            for leavesays in leavesayslist:
                print(leavesays)
                sayswho = leavesays[0]
                issaysinfamily = leavesays[1]
                familyid=leavesays[2]
                saystime=leavesays[3]
                says=leavesays[4]
                if issaysinfamily != 1:
                    familyid = 0
                print(sayswho, self.__ikey, issaysinfamily, familyid, saystime, says)
                self.__qonline.recvsays(sayswho, self.__ikey, issaysinfamily, familyid, saystime, says)
            pass
        else:
            pass

    #定义so控制处理方法，处理下层连接up/DOWN通知，注册给clientso使用
    def do_socon(self,con_type):
        if con_type == self.__clientso.CON_DOWN:
            self._log('here clientso down.')
            self.__qonline.disconnect()
            pass
        elif con_type == self.__clientso.CON_UP:
            self._log('here clientso up.')
            self.__qonline.reconnect()
            #这里可能要重新登录认证
            pass
        else:
            pass
